using System;
using System.Collections.Generic;
using System.Text;
using FireStarter.CodeGeneration.Parser;
using NUnit.Framework;

namespace FireStarter.Test.CodeGeneration.Parser
{
    [TestFixture]
    public class TestParserUtilities
    {

        private int GetIndexOfOccurence(string endTag, string text, int occurrence)
        {
            int pos = 0 - endTag.Length;
            for (int i = 0; i < occurrence; i++)
            {
                pos = text.IndexOf(endTag, pos + endTag.Length);
            }
            return pos;
        }

        [Test]
        public void Test_IndexOfCorrespondingEndTag_AtBeginning()
        {
            //---------------Set up test pack-------------------
            string text = ")" + TestUtilsCodeGen.GetRandomString();
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            int pos = ParserUtilities.IndexOfCorrespondingEndTag("(", ")", text);
            //---------------Test Result -----------------------
            Assert.AreEqual(0, pos);
        }

        [Test]
        public void Test_IndexOfCorrespondingEndTag_AtEnd()
        {
            //---------------Set up test pack-------------------
            string text = TestUtilsCodeGen.GetRandomWhiteSpace() + ")";
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            int pos = ParserUtilities.IndexOfCorrespondingEndTag("(", ")", text);
            //---------------Test Result -----------------------
            Assert.AreEqual(text.Length - 1, pos);
        }

        [Test]
        public void Test_IndexOfCorrespondingEndTag_IgnoreBrackets()
        {
            //---------------Set up test pack-------------------
            const string startTag = "(";
            const string endTag = ")";
            string text = string.Format("{0}aaa{1}bbb{1}ccc", startTag, endTag);
            int expectedPos = GetIndexOfOccurence(endTag, text, 2);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            int pos = ParserUtilities.IndexOfCorrespondingEndTag(startTag, endTag, text);
            //---------------Test Result -----------------------
            Assert.AreEqual(expectedPos, pos);
        }

        [Test]
        public void Test_IndexOfCorrespondingEndTag_IgnoreBrackets_ComplexTags()
        {
            //---------------Set up test pack-------------------
            const string startTag = "<<|";
            const string endTag = "|>>";
            string text = string.Format("{0}aaa{1}bbb{1}ccc", startTag, endTag);
            int expectedPos = GetIndexOfOccurence(endTag, text, 2);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            int pos = ParserUtilities.IndexOfCorrespondingEndTag(startTag, endTag, text);
            //---------------Test Result -----------------------
            Assert.AreEqual(expectedPos, pos);
        }

        [Test]
        public void Test_IndexOfCorrespondingEndTag_IgnoreDoubleBrackets()
        {
            //---------------Set up test pack-------------------
            const string startTag = "(";
            const string endTag = ")";
            string text = string.Format("{0}a{0}a{1}a{1}bbb{1}ccc", startTag, endTag);
            int expectedPos = GetIndexOfOccurence(endTag, text, 3);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            int pos = ParserUtilities.IndexOfCorrespondingEndTag(startTag, endTag, text);
            //---------------Test Result -----------------------
            Assert.AreEqual(expectedPos, pos);
        }

        [Test]
        public void Test_IndexOfCorrespondingEndTag_IgnoreDoubleBrackets_ComplexTags()
        {
            //---------------Set up test pack-------------------
            const string startTag = "<<|";
            const string endTag = "|>>";
            string text = string.Format("{0}a{0}a{1}a{1}bbb{1}ccc", startTag, endTag);
            int expectedPos = GetIndexOfOccurence(endTag, text, 3);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            int pos = ParserUtilities.IndexOfCorrespondingEndTag(startTag, endTag, text);
            //---------------Test Result -----------------------
            Assert.AreEqual(expectedPos, pos);
        }

        [Test]
        public void Test_IndexOfCorrespondingEndTag_ReturnsFirstClosingTag()
        {
            //---------------Set up test pack-------------------
            const string startTag = "<<|";
            const string endTag = "|>>";
            string text = string.Format("aaa{1}bbb{0}cc{1}c", startTag, endTag);
            int expectedPos = GetIndexOfOccurence(endTag, text, 1);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            int pos = ParserUtilities.IndexOfCorrespondingEndTag(startTag, endTag, text);
            //---------------Test Result -----------------------
            Assert.AreEqual(expectedPos, pos);
        }

        [Test]
        public void Test_IndexOfCorrespondingEndTag_Complex()
        {
            //---------------Set up test pack-------------------
            const string startTag = "<<";
            const string endTag = ">>";
            string text = "<<a>><<<<b>>>><<>>>>cc";
            int expectedPos = GetIndexOfOccurence(endTag, text, 5);
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            int pos = ParserUtilities.IndexOfCorrespondingEndTag(startTag, endTag, text);
            //---------------Test Result -----------------------
            Assert.AreEqual(expectedPos, pos);
        }
    }
}
